package com.school.sports.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.school.sports.entity.Volunteer;
import com.school.sports.entity.VolunteerApplication;
import com.school.sports.entity.VolunteerTask;
import com.school.sports.service.VolunteerService;
import com.school.sports.common.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 志愿者管理控制器
 * 提供志愿者申请、任务分配、服务记录、统计分析、评价管理、工作负载等功能
 */
@RestController
@RequestMapping("/api/volunteers")
@Validated
public class VolunteerController {

    private static final Logger logger = LoggerFactory.getLogger(VolunteerController.class);

    @Autowired
    private VolunteerService volunteerService;

    // ==================== 志愿者申请管理接口 ====================

    /**
     * 提交志愿者申请
     * @param application 申请信息
     * @return 申请结果
     */
    @PostMapping("/applications")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<String> submitApplication(@Valid @RequestBody VolunteerApplication application) {
        logger.info("提交志愿者申请，用户ID：{}", application.getUserId());

        try {
            boolean success = volunteerService.submitApplication(application);
            if (success) {
                logger.info("志愿者申请提交成功，用户ID：{}", application.getUserId());
                return Result.success("申请提交成功");
            } else {
                return Result.error("申请提交失败");
            }
        } catch (Exception e) {
            logger.error("提交志愿者申请异常：{}", e.getMessage(), e);
            return Result.error("申请提交失败：" + e.getMessage());
        }
    }

    /**
     * 审核志愿者申请
     * @param applicationId 申请ID
     * @param request 审核请求（包含是否通过、审核意见）
     * @return 审核结果
     */
    @PutMapping("/applications/{applicationId}/review")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> reviewApplication(
            @PathVariable("applicationId") Long applicationId,
            @Valid @RequestBody ReviewApplicationRequest request) {

        logger.info("审核志愿者申请，申请ID：{}，审核结果：{}", applicationId, request.isApproved());

        try {
            // 这里需要从Spring Security获取当前用户ID，简化处理
            Long reviewerId = 1L; // 实际应该从SecurityContext获取

            boolean success = volunteerService.reviewApplication(
                    applicationId,
                    request.isApproved(),
                    request.getReviewComment(),
                    reviewerId
            );

            if (success) {
                logger.info("志愿者申请审核成功，申请ID：{}", applicationId);
                return Result.success("审核完成");
            } else {
                return Result.error("审核失败");
            }
        } catch (Exception e) {
            logger.error("审核志愿者申请异常：{}", e.getMessage(), e);
            return Result.error("审核失败：" + e.getMessage());
        }
    }

    /**
     * 取消志愿者申请
     * @param applicationId 申请ID
     * @param request 取消请求（包含取消原因）
     * @return 取消结果
     */
    @PutMapping("/applications/{applicationId}/cancel")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<String> cancelApplication(
            @PathVariable("applicationId") Long applicationId,
            @Valid @RequestBody CancelApplicationRequest request) {

        logger.info("取消志愿者申请，申请ID：{}，原因：{}", applicationId, request.getCancelReason());

        try {
            boolean success = volunteerService.cancelApplication(applicationId, request.getCancelReason());
            if (success) {
                logger.info("志愿者申请取消成功，申请ID：{}", applicationId);
                return Result.success("申请已取消");
            } else {
                return Result.error("取消失败");
            }
        } catch (Exception e) {
            logger.error("取消志愿者申请异常：{}", e.getMessage(), e);
            return Result.error("取消失败：" + e.getMessage());
        }
    }

    /**
     * 分页查询志愿者申请列表
     * @param currentPage 当前页码
     * @param pageSize 每页大小
     * @param application 查询条件
     * @return 分页结果
     */
    @GetMapping("/applications/page/{currentPage}/{pageSize}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<IPage<VolunteerApplication>> getApplicationPage(
            @PathVariable("currentPage") Integer currentPage,
            @PathVariable("pageSize") Integer pageSize,
            VolunteerApplication application) {

        logger.info("分页查询志愿者申请列表，当前页码：{}，每页条数：{}", currentPage, pageSize);

        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }

        try {
            IPage<VolunteerApplication> page = volunteerService.getApplicationPage(currentPage, pageSize, application);
            logger.info("查询志愿者申请列表成功，共{}条记录", page.getTotal());
            return Result.success(page);
        } catch (Exception e) {
            logger.error("查询志愿者申请列表异常：{}", e.getMessage(), e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户申请列表
     * @param userId 用户ID
     * @return 申请列表
     */
    @GetMapping("/applications/user/{userId}")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<List<VolunteerApplication>> getApplicationsByUserId(@PathVariable("userId") Long userId) {
        logger.info("获取用户申请列表，用户ID：{}", userId);

        try {
            List<VolunteerApplication> applications = volunteerService.getApplicationsByUserId(userId);
            logger.info("获取用户申请列表成功，共{}条记录", applications.size());
            return Result.success(applications);
        } catch (Exception e) {
            logger.error("获取用户申请列表异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取待审核申请数量
     * @return 待审核数量
     */
    @GetMapping("/applications/pending-count")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Integer> getPendingApplicationCount() {
        logger.info("获取待审核申请数量");

        try {
            int count = volunteerService.getPendingApplicationCount();
            logger.info("获取待审核申请数量成功：{}", count);
            return Result.success(count);
        } catch (Exception e) {
            logger.error("获取待审核申请数量异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    // ==================== 志愿者任务分配接口 ====================

    /**
     * 分配志愿者任务
     * @param task 任务信息
     * @return 分配结果
     */
    @PostMapping("/tasks")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> assignTask(@Valid @RequestBody VolunteerTask task) {
        logger.info("分配志愿者任务，志愿者ID：{}，任务内容：{}", task.getVolunteerId(), task.getTaskContent());

        try {
            boolean success = volunteerService.assignTask(task);
            if (success) {
                logger.info("志愿者任务分配成功，志愿者ID：{}", task.getVolunteerId());
                return Result.success("任务分配成功");
            } else {
                return Result.error("任务分配失败");
            }
        } catch (Exception e) {
            logger.error("分配志愿者任务异常：{}", e.getMessage(), e);
            return Result.error("任务分配失败：" + e.getMessage());
        }
    }

    /**
     * 批量分配志愿者任务
     * @param tasks 任务列表
     * @return 分配结果
     */
    @PostMapping("/tasks/batch")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> batchAssignTasks(@Valid @RequestBody List<VolunteerTask> tasks) {
        logger.info("批量分配志愿者任务，任务数量：{}", tasks.size());

        try {
            boolean success = volunteerService.batchAssignTasks(tasks);
            if (success) {
                logger.info("批量分配志愿者任务成功，共{}个任务", tasks.size());
                return Result.success("批量分配成功");
            } else {
                return Result.error("批量分配失败");
            }
        } catch (Exception e) {
            logger.error("批量分配志愿者任务异常：{}", e.getMessage(), e);
            return Result.error("批量分配失败：" + e.getMessage());
        }
    }

    /**
     * 更新任务状态
     * @param taskId 任务ID
     * @param request 状态更新请求
     * @return 更新结果
     */
    @PutMapping("/tasks/{taskId}/status")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<String> updateTaskStatus(
            @PathVariable("taskId") Long taskId,
            @Valid @RequestBody UpdateTaskStatusRequest request) {

        logger.info("更新任务状态，任务ID：{}，新状态：{}", taskId, request.getStatus());

        try {
            boolean success = volunteerService.updateTaskStatus(taskId, request.getStatus());
            if (success) {
                logger.info("任务状态更新成功，任务ID：{}", taskId);
                return Result.success("状态更新成功");
            } else {
                return Result.error("状态更新失败");
            }
        } catch (Exception e) {
            logger.error("更新任务状态异常：{}", e.getMessage(), e);
            return Result.error("状态更新失败：" + e.getMessage());
        }
    }

    /**
     * 开始执行任务
     * @param taskId 任务ID
     * @return 执行结果
     */
    @PutMapping("/tasks/{taskId}/start")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<String> startTask(@PathVariable("taskId") Long taskId) {
        logger.info("开始执行任务，任务ID：{}", taskId);

        try {
            boolean success = volunteerService.startTask(taskId);
            if (success) {
                logger.info("任务开始执行成功，任务ID：{}", taskId);
                return Result.success("任务已开始");
            } else {
                return Result.error("任务开始失败");
            }
        } catch (Exception e) {
            logger.error("开始执行任务异常：{}", e.getMessage(), e);
            return Result.error("任务开始失败：" + e.getMessage());
        }
    }

    /**
     * 完成任务
     * @param taskId 任务ID
     * @param request 完成任务请求（包含反馈信息）
     * @return 完成结果
     */
    @PutMapping("/tasks/{taskId}/complete")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<String> completeTask(
            @PathVariable("taskId") Long taskId,
            @Valid @RequestBody CompleteTaskRequest request) {

        logger.info("完成任务，任务ID：{}，反馈：{}", taskId, request.getFeedback());

        try {
            boolean success = volunteerService.completeTask(taskId, request.getFeedback());
            if (success) {
                logger.info("任务完成成功，任务ID：{}", taskId);
                return Result.success("任务已完成");
            } else {
                return Result.error("任务完成失败");
            }
        } catch (Exception e) {
            logger.error("完成任务异常：{}", e.getMessage(), e);
            return Result.error("任务完成失败：" + e.getMessage());
        }
    }

    /**
     * 取消任务
     * @param taskId 任务ID
     * @param request 取消任务请求（包含取消原因）
     * @return 取消结果
     */
    @PutMapping("/tasks/{taskId}/cancel")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> cancelTask(
            @PathVariable("taskId") Long taskId,
            @Valid @RequestBody CancelTaskRequest request) {

        logger.info("取消任务，任务ID：{}，原因：{}", taskId, request.getCancelReason());

        try {
            boolean success = volunteerService.cancelTask(taskId, request.getCancelReason());
            if (success) {
                logger.info("任务取消成功，任务ID：{}", taskId);
                return Result.success("任务已取消");
            } else {
                return Result.error("任务取消失败");
            }
        } catch (Exception e) {
            logger.error("取消任务异常：{}", e.getMessage(), e);
            return Result.error("任务取消失败：" + e.getMessage());
        }
    }

    /**
     * 分页查询志愿者任务列表
     * @param currentPage 当前页码
     * @param pageSize 每页大小
     * @param task 查询条件
     * @return 分页结果
     */
    @GetMapping("/tasks/page/{currentPage}/{pageSize}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<IPage<VolunteerTask>> getTaskPage(
            @PathVariable("currentPage") Integer currentPage,
            @PathVariable("pageSize") Integer pageSize,
            VolunteerTask task) {

        logger.info("分页查询志愿者任务列表，当前页码：{}，每页条数：{}", currentPage, pageSize);

        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }

        try {
            IPage<VolunteerTask> page = volunteerService.getTaskPage(currentPage, pageSize, task);
            logger.info("查询志愿者任务列表成功，共{}条记录", page.getTotal());
            return Result.success(page);
        } catch (Exception e) {
            logger.error("查询志愿者任务列表异常：{}", e.getMessage(), e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者任务列表
     * @param volunteerId 志愿者ID
     * @return 任务列表
     */
    @GetMapping("/tasks/volunteer/{volunteerId}")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<List<VolunteerTask>> getTasksByVolunteerId(@PathVariable("volunteerId") Long volunteerId) {
        logger.info("获取志愿者任务列表，志愿者ID：{}", volunteerId);

        try {
            List<VolunteerTask> tasks = volunteerService.getTasksByVolunteerId(volunteerId);
            logger.info("获取志愿者任务列表成功，共{}条记录", tasks.size());
            return Result.success(tasks);
        } catch (Exception e) {
            logger.error("获取志愿者任务列表异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取进行中的任务列表
     * @return 任务列表
     */
    @GetMapping("/tasks/ongoing")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<List<VolunteerTask>> getOngoingTasks() {
        logger.info("获取进行中的任务列表");

        try {
            List<VolunteerTask> tasks = volunteerService.getOngoingTasks();
            logger.info("获取进行中的任务列表成功，共{}条记录", tasks.size());
            return Result.success(tasks);
        } catch (Exception e) {
            logger.error("获取进行中的任务列表异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取即将开始的任务（1小时内）
     * @return 任务列表
     */
    @GetMapping("/tasks/upcoming")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<List<VolunteerTask>> getUpcomingTasks() {
        logger.info("获取即将开始的任务列表");

        try {
            List<VolunteerTask> tasks = volunteerService.getUpcomingTasks();
            logger.info("获取即将开始的任务列表成功，共{}条记录", tasks.size());
            return Result.success(tasks);
        } catch (Exception e) {
            logger.error("获取即将开始的任务列表异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    // ==================== 志愿者服务记录查询接口 ====================

    /**
     * 获取志愿者服务记录
     * @param volunteerId 志愿者ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 服务记录列表
     */
    @GetMapping("/records/{volunteerId}")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<List<VolunteerTask>> getServiceRecords(
            @PathVariable("volunteerId") Long volunteerId,
            @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("获取志愿者服务记录，志愿者ID：{}，时间范围：{} - {}", volunteerId, startTime, endTime);

        try {
            List<VolunteerTask> records = volunteerService.getServiceRecords(volunteerId, startTime, endTime);
            logger.info("获取志愿者服务记录成功，共{}条记录", records.size());
            return Result.success(records);
        } catch (Exception e) {
            logger.error("获取志愿者服务记录异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 计算志愿者总服务时长
     * @param volunteerId 志愿者ID
     * @return 服务时长（小时）
     */
    @GetMapping("/records/{volunteerId}/total-hours")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<Integer> calculateTotalServiceHours(@PathVariable("volunteerId") Long volunteerId) {
        logger.info("计算志愿者总服务时长，志愿者ID：{}", volunteerId);

        try {
            Integer hours = volunteerService.calculateTotalServiceHours(volunteerId);
            logger.info("计算志愿者总服务时长成功：{}小时", hours);
            return Result.success(hours);
        } catch (Exception e) {
            logger.error("计算志愿者总服务时长异常：{}", e.getMessage(), e);
            return Result.error("计算失败：" + e.getMessage());
        }
    }

    /**
     * 计算指定时间段内的服务时长
     * @param volunteerId 志愿者ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 服务时长（小时）
     */
    @GetMapping("/records/{volunteerId}/hours-in-range")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<Integer> calculateServiceHoursInRange(
            @PathVariable("volunteerId") Long volunteerId,
            @RequestParam("startTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam("endTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("计算指定时间段内的服务时长，志愿者ID：{}，时间范围：{} - {}", volunteerId, startTime, endTime);

        try {
            Integer hours = volunteerService.calculateServiceHoursInRange(volunteerId, startTime, endTime);
            logger.info("计算指定时间段内的服务时长成功：{}小时", hours);
            return Result.success(hours);
        } catch (Exception e) {
            logger.error("计算指定时间段内的服务时长异常：{}", e.getMessage(), e);
            return Result.error("计算失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者服务统计信息
     * @param volunteerId 志愿者ID
     * @return 统计信息
     */
    @GetMapping("/records/{volunteerId}/statistics")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<Map<String, Object>> getServiceStatistics(@PathVariable("volunteerId") Long volunteerId) {
        logger.info("获取志愿者服务统计信息，志愿者ID：{}", volunteerId);

        try {
            Map<String, Object> statistics = volunteerService.getServiceStatistics(volunteerId);
            logger.info("获取志愿者服务统计信息成功，志愿者ID：{}", volunteerId);
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取志愿者服务统计信息异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 生成志愿者服务证书
     * @param volunteerId 志愿者ID
     * @param certificateType 证书类型
     * @return 证书信息
     */
    @GetMapping("/records/{volunteerId}/certificate")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<Map<String, Object>> generateServiceCertificate(
            @PathVariable("volunteerId") Long volunteerId,
            @RequestParam("certificateType") String certificateType) {

        logger.info("生成志愿者服务证书，志愿者ID：{}，证书类型：{}", volunteerId, certificateType);

        try {
            Map<String, Object> certificate = volunteerService.generateServiceCertificate(volunteerId, certificateType);
            logger.info("生成志愿者服务证书成功，志愿者ID：{}", volunteerId);
            return Result.success(certificate);
        } catch (Exception e) {
            logger.error("生成志愿者服务证书异常：{}", e.getMessage(), e);
            return Result.error("生成失败：" + e.getMessage());
        }
    }

    // ==================== 志愿者统计分析接口 ====================

    /**
     * 获取志愿者总数统计
     * @return 统计信息
     */
    @GetMapping("/statistics/count")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Map<String, Object>> getVolunteerCountStatistics() {
        logger.info("获取志愿者总数统计");

        try {
            Map<String, Object> statistics = volunteerService.getVolunteerCountStatistics();
            logger.info("获取志愿者总数统计成功");
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取志愿者总数统计异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者活跃度统计
     * @param days 统计天数
     * @return 活跃度统计
     */
    @GetMapping("/statistics/activity")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Map<String, Object>> getActivityStatistics(
            @RequestParam(value = "days", defaultValue = "30") Integer days) {

        logger.info("获取志愿者活跃度统计，统计天数：{}", days);

        try {
            Map<String, Object> statistics = volunteerService.getActivityStatistics(days);
            logger.info("获取志愿者活跃度统计成功");
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取志愿者活跃度统计异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者服务时长排行
     * @param limit 排行榜数量限制
     * @param timeRange 时间范围（月、季、年）
     * @return 排行榜
     */
    @GetMapping("/statistics/service-hours-ranking")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<List<Map<String, Object>>> getServiceHoursRanking(
            @RequestParam(value = "limit", defaultValue = "10") Integer limit,
            @RequestParam(value = "timeRange", defaultValue = "月") String timeRange) {

        logger.info("获取志愿者服务时长排行，限制：{}，时间范围：{}", limit, timeRange);

        try {
            List<Map<String, Object>> ranking = volunteerService.getServiceHoursRanking(limit, timeRange);
            logger.info("获取志愿者服务时长排行成功，共{}条记录", ranking.size());
            return Result.success(ranking);
        } catch (Exception e) {
            logger.error("获取志愿者服务时长排行异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者任务完成率统计
     * @param timeRange 时间范围
     * @return 完成率统计
     */
    @GetMapping("/statistics/task-completion-rate")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Map<String, Object>> getTaskCompletionRate(
            @RequestParam(value = "timeRange", defaultValue = "月") String timeRange) {

        logger.info("获取志愿者任务完成率统计，时间范围：{}", timeRange);

        try {
            Map<String, Object> statistics = volunteerService.getTaskCompletionRate(timeRange);
            logger.info("获取志愿者任务完成率统计成功");
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取志愿者任务完成率统计异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者分布统计（按学院、班级等）
     * @param groupBy 分组字段
     * @return 分布统计
     */
    @GetMapping("/statistics/distribution")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<List<Map<String, Object>>> getVolunteerDistribution(
            @RequestParam(value = "groupBy", defaultValue = "college") String groupBy) {

        logger.info("获取志愿者分布统计，分组字段：{}", groupBy);

        try {
            List<Map<String, Object>> distribution = volunteerService.getVolunteerDistribution(groupBy);
            logger.info("获取志愿者分布统计成功，共{}条记录", distribution.size());
            return Result.success(distribution);
        } catch (Exception e) {
            logger.error("获取志愿者分布统计异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者服务类型统计
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 服务类型统计
     */
    @GetMapping("/statistics/service-type")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Map<String, Object>> getServiceTypeStatistics(
            @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("获取志愿者服务类型统计，时间范围：{} - {}", startTime, endTime);

        try {
            Map<String, Object> statistics = volunteerService.getServiceTypeStatistics(startTime, endTime);
            logger.info("获取志愿者服务类型统计成功");
            return Result.success(statistics);
        } catch (Exception e) {
            logger.error("获取志愿者服务类型统计异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    // ==================== 志愿者评价管理接口 ====================

    /**
     * 评价志愿者任务表现
     * @param taskId 任务ID
     * @param request 评价请求（包含评分、评价内容）
     * @return 评价结果
     */
    @PostMapping("/evaluations/{taskId}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> evaluateTask(
            @PathVariable("taskId") Long taskId,
            @Valid @RequestBody EvaluateTaskRequest request) {

        logger.info("评价志愿者任务表现，任务ID：{}，评分：{}", taskId, request.getRating());

        try {
            // 这里需要从Spring Security获取当前用户ID，简化处理
            Long evaluatorId = 1L; // 实际应该从SecurityContext获取

            boolean success = volunteerService.evaluateTask(taskId, request.getRating(), request.getComment(), evaluatorId);
            if (success) {
                logger.info("志愿者任务评价成功，任务ID：{}", taskId);
                return Result.success("评价成功");
            } else {
                return Result.error("评价失败");
            }
        } catch (Exception e) {
            logger.error("评价志愿者任务表现异常：{}", e.getMessage(), e);
            return Result.error("评价失败：" + e.getMessage());
        }
    }

    /**
     * 批量评价任务
     * @param evaluations 评价列表（包含任务ID、评分、评价内容等）
     * @return 评价结果
     */
    @PostMapping("/evaluations/batch")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> batchEvaluateTasks(@Valid @RequestBody List<Map<String, Object>> evaluations) {
        logger.info("批量评价任务，评价数量：{}", evaluations.size());

        try {
            boolean success = volunteerService.batchEvaluateTasks(evaluations);
            if (success) {
                logger.info("批量评价任务成功，共{}个评价", evaluations.size());
                return Result.success("批量评价成功");
            } else {
                return Result.error("批量评价失败");
            }
        } catch (Exception e) {
            logger.error("批量评价任务异常：{}", e.getMessage(), e);
            return Result.error("批量评价失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者平均评分
     * @param volunteerId 志愿者ID
     * @return 平均评分
     */
    @GetMapping("/evaluations/{volunteerId}/average-rating")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<Double> getAverageRating(@PathVariable("volunteerId") Long volunteerId) {
        logger.info("获取志愿者平均评分，志愿者ID：{}", volunteerId);

        try {
            Double rating = volunteerService.getAverageRating(volunteerId);
            logger.info("获取志愿者平均评分成功：{}", rating);
            return Result.success(rating);
        } catch (Exception e) {
            logger.error("获取志愿者平均评分异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者评价记录
     * @param volunteerId 志愿者ID
     * @param currentPage 当前页码
     * @param pageSize 每页大小
     * @return 评价记录
     */
    @GetMapping("/evaluations/{volunteerId}/records/{currentPage}/{pageSize}")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<IPage<Map<String, Object>>> getEvaluationRecords(
            @PathVariable("volunteerId") Long volunteerId,
            @PathVariable("currentPage") Integer currentPage,
            @PathVariable("pageSize") Integer pageSize) {

        logger.info("获取志愿者评价记录，志愿者ID：{}，当前页码：{}，每页条数：{}", volunteerId, currentPage, pageSize);

        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }

        try {
            IPage<Map<String, Object>> records = volunteerService.getEvaluationRecords(volunteerId, currentPage, pageSize);
            logger.info("获取志愿者评价记录成功，共{}条记录", records.getTotal());
            return Result.success(records);
        } catch (Exception e) {
            logger.error("获取志愿者评价记录异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取优秀志愿者列表
     * @param limit 数量限制
     * @param minRating 最低评分要求
     * @return 优秀志愿者列表
     */
    @GetMapping("/evaluations/outstanding")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<List<Volunteer>> getOutstandingVolunteers(
            @RequestParam(value = "limit", defaultValue = "10") Integer limit,
            @RequestParam(value = "minRating", defaultValue = "4.0") Double minRating) {

        logger.info("获取优秀志愿者列表，限制：{}，最低评分：{}", limit, minRating);

        try {
            List<Volunteer> volunteers = volunteerService.getOutstandingVolunteers(limit, minRating);
            logger.info("获取优秀志愿者列表成功，共{}条记录", volunteers.size());
            return Result.success(volunteers);
        } catch (Exception e) {
            logger.error("获取优秀志愿者列表异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    // ==================== 志愿者工作负载管理接口 ====================

    /**
     * 检查志愿者是否可以接受新任务
     * @param volunteerId 志愿者ID
     * @return 是否可以接受
     */
    @GetMapping("/workload/{volunteerId}/can-accept-task")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Boolean> canAcceptNewTask(@PathVariable("volunteerId") Long volunteerId) {
        logger.info("检查志愿者是否可以接受新任务，志愿者ID：{}", volunteerId);

        try {
            boolean canAccept = volunteerService.canAcceptNewTask(volunteerId);
            logger.info("检查志愿者是否可以接受新任务成功，结果：{}", canAccept);
            return Result.success(canAccept);
        } catch (Exception e) {
            logger.error("检查志愿者是否可以接受新任务异常：{}", e.getMessage(), e);
            return Result.error("检查失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者当前工作负载
     * @param volunteerId 志愿者ID
     * @return 工作负载信息
     */
    @GetMapping("/workload/{volunteerId}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Map<String, Object>> getWorkload(@PathVariable("volunteerId") Long volunteerId) {
        logger.info("获取志愿者当前工作负载，志愿者ID：{}", volunteerId);

        try {
            Map<String, Object> workload = volunteerService.getWorkload(volunteerId);
            logger.info("获取志愿者当前工作负载成功，志愿者ID：{}", volunteerId);
            return Result.success(workload);
        } catch (Exception e) {
            logger.error("获取志愿者当前工作负载异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 获取可用志愿者列表（可接受新任务）
     * @param startTime 任务开始时间
     * @param endTime 任务结束时间
     * @return 可用志愿者列表
     */
    @GetMapping("/workload/available-volunteers")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<List<Volunteer>> getAvailableVolunteers(
            @RequestParam("startTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam("endTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("获取可用志愿者列表，时间范围：{} - {}", startTime, endTime);

        try {
            List<Volunteer> volunteers = volunteerService.getAvailableVolunteers(startTime, endTime);
            logger.info("获取可用志愿者列表成功，共{}条记录", volunteers.size());
            return Result.success(volunteers);
        } catch (Exception e) {
            logger.error("获取可用志愿者列表异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 智能推荐志愿者
     * @param projectId 项目ID
     * @param venueId 场地ID
     * @param taskContent 任务内容
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 推荐志愿者列表
     */
    @GetMapping("/workload/recommend-volunteers")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<List<Volunteer>> recommendVolunteers(
            @RequestParam(value = "projectId", required = false) Long projectId,
            @RequestParam(value = "venueId", required = false) Integer venueId,
            @RequestParam(value = "taskContent") String taskContent,
            @RequestParam("startTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam("endTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("智能推荐志愿者，项目ID：{}，场地ID：{}，任务内容：{}", projectId, venueId, taskContent);

        try {
            List<Volunteer> volunteers = volunteerService.recommendVolunteers(projectId, venueId, taskContent, startTime, endTime);
            logger.info("智能推荐志愿者成功，共{}条记录", volunteers.size());
            return Result.success(volunteers);
        } catch (Exception e) {
            logger.error("智能推荐志愿者异常：{}", e.getMessage(), e);
            return Result.error("推荐失败：" + e.getMessage());
        }
    }

    /**
     * 检查志愿者时间冲突
     * @param volunteerId 志愿者ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 是否有时间冲突
     */
    @GetMapping("/workload/{volunteerId}/time-conflict")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Boolean> hasTimeConflict(
            @PathVariable("volunteerId") Long volunteerId,
            @RequestParam("startTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam("endTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {

        logger.info("检查志愿者时间冲突，志愿者ID：{}，时间范围：{} - {}", volunteerId, startTime, endTime);

        try {
            boolean hasConflict = volunteerService.hasTimeConflict(volunteerId, startTime, endTime);
            logger.info("检查志愿者时间冲突成功，结果：{}", hasConflict);
            return Result.success(hasConflict);
        } catch (Exception e) {
            logger.error("检查志愿者时间冲突异常：{}", e.getMessage(), e);
            return Result.error("检查失败：" + e.getMessage());
        }
    }

    // ==================== 志愿者基本信息管理接口 ====================

    /**
     * 验证志愿者资质
     * @param volunteerId 志愿者ID
     * @param verificationType 验证类型
     * @return 验证结果
     */
    @PostMapping("/{volunteerId}/verify")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<Boolean> verifyVolunteerQualification(
            @PathVariable("volunteerId") Long volunteerId,
            @RequestParam("verificationType") String verificationType) {

        logger.info("验证志愿者资质，志愿者ID：{}，验证类型：{}", volunteerId, verificationType);

        try {
            boolean isValid = volunteerService.verifyVolunteerQualification(volunteerId, verificationType);
            logger.info("验证志愿者资质成功，结果：{}", isValid);
            return Result.success(isValid);
        } catch (Exception e) {
            logger.error("验证志愿者资质异常：{}", e.getMessage(), e);
            return Result.error("验证失败：" + e.getMessage());
        }
    }

    /**
     * 更新志愿者状态
     * @param volunteerId 志愿者ID
     * @param status 志愿者状态
     * @return 更新结果
     */
    @PutMapping("/{volunteerId}/status")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> updateVolunteerStatus(
            @PathVariable("volunteerId") Long volunteerId,
            @RequestParam("status") String status) {

        logger.info("更新志愿者状态，志愿者ID：{}，状态：{}", volunteerId, status);

        try {
            boolean success = volunteerService.updateVolunteerStatus(volunteerId, status);
            if (success) {
                logger.info("更新志愿者状态成功，志愿者ID：{}", volunteerId);
                return Result.success("状态更新成功");
            } else {
                return Result.error("状态更新失败");
            }
        } catch (Exception e) {
            logger.error("更新志愿者状态异常：{}", e.getMessage(), e);
            return Result.error("状态更新失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者详细信息
     * @param volunteerId 志愿者ID
     * @return 志愿者详细信息
     */
    @GetMapping("/{volunteerId}")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<Volunteer> getVolunteerDetails(@PathVariable("volunteerId") Long volunteerId) {
        logger.info("获取志愿者详细信息，志愿者ID：{}", volunteerId);

        try {
            Volunteer volunteer = volunteerService.getVolunteerDetails(volunteerId);
            if (volunteer != null) {
                logger.info("获取志愿者详细信息成功，志愿者ID：{}", volunteerId);
                return Result.success(volunteer);
            } else {
                return Result.error("志愿者不存在");
            }
        } catch (Exception e) {
            logger.error("获取志愿者详细信息异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 分页查询志愿者列表
     * @param currentPage 当前页码
     * @param pageSize 每页大小
     * @param volunteer 查询条件
     * @return 分页结果
     */
    @GetMapping("/page/{currentPage}/{pageSize}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<IPage<Volunteer>> getVolunteerPage(
            @PathVariable("currentPage") Integer currentPage,
            @PathVariable("pageSize") Integer pageSize,
            Volunteer volunteer) {

        logger.info("分页查询志愿者列表，当前页码：{}，每页条数：{}", currentPage, pageSize);

        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }

        try {
            IPage<Volunteer> page = volunteerService.getVolunteerPage(currentPage, pageSize, volunteer);
            logger.info("查询志愿者列表成功，共{}条记录", page.getTotal());
            return Result.success(page);
        } catch (Exception e) {
            logger.error("查询志愿者列表异常：{}", e.getMessage(), e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }

    /**
     * 批量更新志愿者状态
     * @param request 批量更新请求
     * @return 更新结果
     */
    @PutMapping("/batch/status")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> batchUpdateVolunteerStatus(@Valid @RequestBody BatchUpdateVolunteerStatusRequest request) {
        logger.info("批量更新志愿者状态，志愿者数量：{}，状态：{}", request.getVolunteerIds().size(), request.getStatus());

        try {
            boolean success = volunteerService.batchUpdateVolunteerStatus(request.getVolunteerIds(), request.getStatus());
            if (success) {
                logger.info("批量更新志愿者状态成功，共{}个志愿者", request.getVolunteerIds().size());
                return Result.success("批量更新成功");
            } else {
                return Result.error("批量更新失败");
            }
        } catch (Exception e) {
            logger.error("批量更新志愿者状态异常：{}", e.getMessage(), e);
            return Result.error("批量更新失败：" + e.getMessage());
        }
    }

    // ==================== 志愿者管理功能接口 ====================

    /**
     * 检查用户是否为志愿者
     * @param userId 用户ID
     * @return 是否为志愿者
     */
    @GetMapping("/check/{userId}")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<Boolean> isVolunteer(@PathVariable("userId") Long userId) {
        logger.info("检查用户是否为志愿者，用户ID：{}", userId);

        try {
            boolean isVolunteer = volunteerService.isVolunteer(userId);
            logger.info("检查用户是否为志愿者成功，结果：{}", isVolunteer);
            return Result.success(isVolunteer);
        } catch (Exception e) {
            logger.error("检查用户是否为志愿者异常：{}", e.getMessage(), e);
            return Result.error("检查失败：" + e.getMessage());
        }
    }

    /**
     * 将用户注册为志愿者
     * @param userId 用户ID
     * @return 注册结果
     */
    @PostMapping("/register/{userId}")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<String> registerAsVolunteer(@PathVariable("userId") Long userId) {
        logger.info("将用户注册为志愿者，用户ID：{}", userId);

        try {
            boolean success = volunteerService.registerAsVolunteer(userId);
            if (success) {
                logger.info("用户注册为志愿者成功，用户ID：{}", userId);
                return Result.success("注册成功");
            } else {
                return Result.error("注册失败");
            }
        } catch (Exception e) {
            logger.error("将用户注册为志愿者异常：{}", e.getMessage(), e);
            return Result.error("注册失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者标签
     * @param volunteerId 志愿者ID
     * @return 标签列表
     */
    @GetMapping("/{volunteerId}/tags")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<List<String>> getVolunteerTags(@PathVariable("volunteerId") Long volunteerId) {
        logger.info("获取志愿者标签，志愿者ID：{}", volunteerId);

        try {
            List<String> tags = volunteerService.getVolunteerTags(volunteerId);
            logger.info("获取志愿者标签成功，志愿者ID：{}，标签数量：{}", volunteerId, tags.size());
            return Result.success(tags);
        } catch (Exception e) {
            logger.error("获取志愿者标签异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    /**
     * 导出志愿者服务记录
     * @param volunteerId 志愿者ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param format 导出格式
     * @return 导出结果
     */
    @GetMapping("/records/{volunteerId}/export")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<Map<String, Object>> exportServiceRecords(
            @PathVariable("volunteerId") Long volunteerId,
            @RequestParam(value = "startTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @RequestParam(value = "format", defaultValue = "excel") String format) {

        logger.info("导出志愿者服务记录，志愿者ID：{}，格式：{}", volunteerId, format);

        try {
            Map<String, Object> result = volunteerService.exportServiceRecords(volunteerId, startTime, endTime, format);
            logger.info("导出志愿者服务记录成功，志愿者ID：{}", volunteerId);
            return Result.success(result);
        } catch (Exception e) {
            logger.error("导出志愿者服务记录异常：{}", e.getMessage(), e);
            return Result.error("导出失败：" + e.getMessage());
        }
    }

    /**
     * 发送志愿者通知
     * @param request 通知请求
     * @return 发送结果
     */
    @PostMapping("/notifications")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<String> sendNotification(@Valid @RequestBody SendNotificationRequest request) {
        logger.info("发送志愿者通知，志愿者数量：{}，标题：{}", request.getVolunteerIds().size(), request.getTitle());

        try {
            boolean success = volunteerService.sendNotification(
                    request.getVolunteerIds(),
                    request.getTitle(),
                    request.getContent(),
                    request.getNotificationType()
            );
            if (success) {
                logger.info("发送志愿者通知成功，共{}个志愿者", request.getVolunteerIds().size());
                return Result.success("通知发送成功");
            } else {
                return Result.error("通知发送失败");
            }
        } catch (Exception e) {
            logger.error("发送志愿者通知异常：{}", e.getMessage(), e);
            return Result.error("通知发送失败：" + e.getMessage());
        }
    }

    /**
     * 获取志愿者绩效报告
     * @param volunteerId 志愿者ID
     * @param reportType 报告类型
     * @param timeRange 时间范围
     * @return 绩效报告
     */
    @GetMapping("/{volunteerId}/performance-report")
    @PreAuthorize("hasAnyRole('学生', '老师', '管理员')")
    public Result<Map<String, Object>> getPerformanceReport(
            @PathVariable("volunteerId") Long volunteerId,
            @RequestParam(value = "reportType", defaultValue = "summary") String reportType,
            @RequestParam(value = "timeRange", defaultValue = "month") String timeRange) {

        logger.info("获取志愿者绩效报告，志愿者ID：{}，报告类型：{}，时间范围：{}", volunteerId, reportType, timeRange);

        try {
            Map<String, Object> report = volunteerService.getPerformanceReport(volunteerId, reportType, timeRange);
            logger.info("获取志愿者绩效报告成功，志愿者ID：{}", volunteerId);
            return Result.success(report);
        } catch (Exception e) {
            logger.error("获取志愿者绩效报告异常：{}", e.getMessage(), e);
            return Result.error("获取失败：" + e.getMessage());
        }
    }

    // ==================== 请求DTO类 ====================

    /**
     * 审核申请请求DTO
     */
    public static class ReviewApplicationRequest {
        private boolean approved;
        @NotNull(message = "审核意见不能为空")
        private String reviewComment;

        public boolean isApproved() {
            return approved;
        }

        public void setApproved(boolean approved) {
            this.approved = approved;
        }

        public String getReviewComment() {
            return reviewComment;
        }

        public void setReviewComment(String reviewComment) {
            this.reviewComment = reviewComment;
        }
    }

    /**
     * 取消申请请求DTO
     */
    public static class CancelApplicationRequest {
        @NotNull(message = "取消原因不能为空")
        private String cancelReason;

        public String getCancelReason() {
            return cancelReason;
        }

        public void setCancelReason(String cancelReason) {
            this.cancelReason = cancelReason;
        }
    }

    /**
     * 更新任务状态请求DTO
     */
    public static class UpdateTaskStatusRequest {
        @NotNull(message = "任务状态不能为空")
        private String status;

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }
    }

    /**
     * 完成任务请求DTO
     */
    public static class CompleteTaskRequest {
        private String feedback;

        public String getFeedback() {
            return feedback;
        }

        public void setFeedback(String feedback) {
            this.feedback = feedback;
        }
    }

    /**
     * 取消任务请求DTO
     */
    public static class CancelTaskRequest {
        @NotNull(message = "取消原因不能为空")
        private String cancelReason;

        public String getCancelReason() {
            return cancelReason;
        }

        public void setCancelReason(String cancelReason) {
            this.cancelReason = cancelReason;
        }
    }

    /**
     * 评价任务请求DTO
     */
    public static class EvaluateTaskRequest {
        @NotNull(message = "评分不能为空")
        private String rating;
        private String comment;

        public String getRating() {
            return rating;
        }

        public void setRating(String rating) {
            this.rating = rating;
        }

        public String getComment() {
            return comment;
        }

        public void setComment(String comment) {
            this.comment = comment;
        }
    }

    /**
     * 批量更新志愿者状态请求DTO
     */
    public static class BatchUpdateVolunteerStatusRequest {
        @NotNull(message = "志愿者ID列表不能为空")
        private List<Long> volunteerIds;
        @NotNull(message = "状态不能为空")
        private String status;

        public List<Long> getVolunteerIds() {
            return volunteerIds;
        }

        public void setVolunteerIds(List<Long> volunteerIds) {
            this.volunteerIds = volunteerIds;
        }

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }
    }

    /**
     * 发送通知请求DTO
     */
    public static class SendNotificationRequest {
        @NotNull(message = "志愿者ID列表不能为空")
        private List<Long> volunteerIds;
        @NotNull(message = "通知标题不能为空")
        private String title;
        @NotNull(message = "通知内容不能为空")
        private String content;
        @NotNull(message = "通知类型不能为空")
        private String notificationType;

        public List<Long> getVolunteerIds() {
            return volunteerIds;
        }

        public void setVolunteerIds(List<Long> volunteerIds) {
            this.volunteerIds = volunteerIds;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }

        public String getNotificationType() {
            return notificationType;
        }

        public void setNotificationType(String notificationType) {
            this.notificationType = notificationType;
        }
    }
}